package com.zhudoo.zhilian.service;

import com.zhudoo.zhilian.dao.entity.User;
import com.zhudoo.zhilian.dao.entity.UserForm;
import com.zhudoo.zhilian.dao.entity.UserRange;
import com.zhudoo.zhilian.dao.entity.UserReport;
import com.zhudoo.zhilian.dao.impl.UserDao;
import com.zhudoo.zhilian.util.*;
import com.zhudoo.zhilian.util.service.UserUtil;
import com.zhudoo.zhilian.util.web.BusinessException;
import com.zhudoo.zhilian.util.web.ResponseUtil;
import com.zhudoo.zhilian.util.web.ServiceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhudao
 */
@Service
public class UserService {
    /**
     * 租客
     */
    public static int TYPE_1 = 1;
    /**
     * 房东
     */
    public static int TYPE_2 = 2;
    /**
     * 经纪人
     */
    public static int TYPE_3 = 3;

    /**
     * 性别未知
     */
    public static int SEX_0 = 0;
    /**
     * 性别男
     */
    public static int SEX_1 = 1;
    /**
     * 性别女
     */
    public static int SEX_2 = 2;
    /**
     * 已提交
     */
    public static int CERTIFICATION_STATUS_1 = 1;
    /**
     * 拒绝
     */
    public static int CERTIFICATION_STATUS_2 = 2;
    /**
     * 通过
     */
    public static int CERTIFICATION_STATUS_3 = 3;

    public static Map<Integer, String> SEX_MAP = new HashMap<Integer, String>() {
        {
            put(SEX_0, "未知");
            put(SEX_1, "男");
            put(SEX_2, "女");
        }
    };

    public static Map<Integer, String> TYPE_MAP = new HashMap<Integer, String>() {
        {
            put(TYPE_1, "租客");
            put(TYPE_2, "房东");
            put(TYPE_3, "经纪人");
        }
    };


    /**
     * 免费
     */
    public static int AGENT_FREE_TYPE_1 = 1;
    /**
     * 收费
     */
    public static int AGENT_FREE_TYPE_2 = 2;

    public static Map<Integer, String> AGENT_FREE_TYPE_MAP = new HashMap<Integer, String>() {
        {
            put(AGENT_FREE_TYPE_1, "免费");
            put(AGENT_FREE_TYPE_2, "收费");
        }
    };

    /**
     * 独立
     */
    public static int AGENT_ROLE_TYPE_1 = 1;
    /**
     * 公司
     */
    public static int AGENT_ROLE_TYPE_2 = 2;

    public static Map<Integer, String> AGENT_ROLE_TYPE_MAP = new HashMap<Integer, String>() {
        {
            put(AGENT_ROLE_TYPE_1, "独立");
            put(AGENT_ROLE_TYPE_2, "公司");
        }
    };

    public static String defaultName = "昵称";
    public static String defaultHeadImg = "http://zhilian.img.zhudoo.com/default.png";


    @Autowired
    UserDao userDao;

    /**
     * 小程序登录
     *
     * @param code
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> loginMiniProgram(String code) {
        Map<String, Object> resultMap = MiniProgramUtil.miniProgramLogin(code);
        String openId = (String) resultMap.get("openid");
        String seesionKey = (String) resultMap.get("session_key");
        Date nowDate = new Date();
        User user = userDao.findUserByOpenId(openId);
        if (user != null && !user.getValid()) {
            throw BusinessException.getInstance(ResponseUtil.INVALID, "您的账号已注销,不允许登陆");
        }
        if (user == null) {
            user = new User();
            user.setOpenId(openId);
            user.setType(TYPE_1);
            user.setSex(SEX_0);
            user.setSessionKey(seesionKey);
            user.setCreateTime(nowDate);
            user.setValid(true);
            TokenUtil.createToken(user);
            user.setCertificationStatus(0);
            user.setNickName(defaultName);
            user.setHeadImg(defaultHeadImg);
            userDao.saveUser(user);
        } else {
            //过期了重新生成TOKEN
            if (user.getTokenExpiredTime().compareTo(nowDate) < 0) {
                TokenUtil.createToken(user);
            }
            user.setSessionKey(seesionKey);
            user.setUpdateTime(nowDate);
            userDao.saveUser(user);
        }
        resultMap.put("token", user.getToken());
        return resultMap;
    }

    /**
     * 小程序获取手机号码
     *
     * @param serviceContext
     */
    @Transactional(rollbackFor = Exception.class)
    public void miniProgramPhone(ServiceContext serviceContext) {
        String token = serviceContext.getParamsString("token");
        String encryptedData = serviceContext.getParamsString("encryptedData");
        String iv = serviceContext.getParamsString("iv");
        User user = userDao.findUserByToken(token);
        Map<String, Object> resultMap = MiniProgramUtil.decrypt(encryptedData, user.getSessionKey(), iv);
        String purePhoneNumber = (String) resultMap.get("purePhoneNumber");
        user.setPhone(purePhoneNumber);
        userDao.saveUser(user);
    }


    /**
     * 修改用户信息
     *
     * @param serviceContext
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(ServiceContext serviceContext) {
        String token = serviceContext.getParamsString("token");
        String phone = serviceContext.getParamsString("phone");
        String nickName = serviceContext.getParamsString("nickName");
        String headImg = serviceContext.getParamsString("headImg");
        String workingAddress = serviceContext.getParamsString("workingAddress");
        String career = serviceContext.getParamsString("career");
        String introduction = serviceContext.getParamsString("introduction");
        Integer type = serviceContext.getParamsInteger("type");
        Integer sex = serviceContext.getParamsInteger("sex");
        Integer age = serviceContext.getParamsInteger("age");
        User user = userDao.findUserByToken(token);
        if (StringUtils.isNotEmpty(phone)) {
            user.setPhone(phone);
        }
        if (type != null && user.getType() == UserService.TYPE_1) {
            user.setType(type);
        }
        if (StringUtils.isNotEmpty(nickName)) {
            if (nickName.trim().length() > 5) {
                nickName = nickName.substring(0, 5);
            }
            user.setNickName(nickName);
        }
        if (StringUtils.isNotEmpty(headImg)) {
            user.setHeadImg(headImg);
        }
        if (sex != null) {
            user.setSex(sex);
        }
        if (age != null) {
            user.setAge(age);
        }
        if (StringUtils.isNotEmpty(workingAddress)) {
            user.setWorkingAddress(workingAddress);
        }
        if (StringUtils.isNotEmpty(career)) {
            user.setCareer(career);
        }
        if (StringUtils.isNotEmpty(introduction)) {
            user.setIntroduction(introduction);
        }
        userDao.saveUser(user);
    }

    @Transactional(rollbackFor = Exception.class)
    public void submitFormId(ServiceContext serviceContext) {
        String formId = serviceContext.getParamsString("formId");
        String info = serviceContext.getParamsString("info");
        String token = serviceContext.getParamsString("token");
        User user = userDao.findUserByToken(token);
        UserForm userForm = new UserForm();
        userForm.setCreateTime(new Date());
        userForm.setFormId(formId);
        userForm.setUserId(user.getId());
        userForm.setValid(true);
        userForm.setFormExpiredTime(DateUtil.addDay(new Date(), 7));
        userForm.setInfo(info);
        userDao.saveUserForm(userForm);
    }

    public Map<String, Object> getUser(ServiceContext serviceContext) {
        Map<String, Object> resultMap = new HashMap<>(20);
        String token = serviceContext.getParamsString("token");
        Integer heUserId = serviceContext.getParamsInteger("heUserId");
        User user;
        if (heUserId == null) {
            user = userDao.findUserByToken(token);
            resultMap.put("phone", StringUtils.isPhone(user.getPhone()) ? user.getPhone() : false);
        } else {
            user = userDao.findUserById(heUserId);
        }
        resultMap.put("userId", user.getId());
        resultMap.put("userType", user.getType());
        resultMap.put("userTypeName", TYPE_MAP.get(user.getType()));
        resultMap.put("nickName", defaultName.equals(user.getNickName()) ? false : user.getNickName());
        resultMap.put("headImg", user.getHeadImg());
        resultMap.put("sex", user.getSex());
        resultMap.put("sexName", SEX_MAP.get(user.getSex()));
        resultMap.put("age", user.getAge());
        resultMap.put("career", user.getCareer());
        resultMap.put("introduction", user.getIntroduction());
        resultMap.put("workingAddress", user.getWorkingAddress());
        //认证信息
        resultMap.put("certificationStatus", user.getCertificationStatus());
        resultMap.put("certificationType", user.getCertificationType());
        resultMap.put("certificationImg", user.getCertificationImg());
        resultMap.put("certificationNote", user.getCertificationNote());
        //经纪人信息
        resultMap.put("agentFreeType", user.getAgentFreeType());
        resultMap.put("agentRoleType", user.getAgentRoleType());
        resultMap.put("agentCompany", user.getAgentCompany());
        resultMap.put("agentPrice", user.getAgentPrice());
        //用户身份提示
        resultMap.put("userTypeBrief", UserUtil.getUserTypeBrief(user));
        return resultMap;
    }

    @Transactional(rollbackFor = Exception.class)
    public void report(ServiceContext serviceContext) {
        String token = serviceContext.getParamsString("token");
        User user = userDao.findUserByToken(token);
        Integer heUserId = serviceContext.getParamsInteger("heUserId");
        Integer reportType = serviceContext.getParamsInteger("reportType");
        UserReport userReport = new UserReport();
        userReport.setHeUserId(heUserId);
        userReport.setReportType(reportType);
        userReport.setValid(true);
        userReport.setUserId(user.getId());
        userDao.saveUserReport(userReport);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addRange(ServiceContext serviceContext) {
        String token = serviceContext.getParamsString("token");
        Integer oneId = serviceContext.getParamsInteger("oneId");
        String oneName = serviceContext.getParamsString("oneName");
        Integer twoId = serviceContext.getParamsInteger("twoId");
        String twoName = serviceContext.getParamsString("twoName");
        User user = userDao.findUserByToken(token);
        UserRange userRange = userDao.findUserRangeByUserIdAndOneIdAndTwoId(user.getId(), oneId, twoId);
        if (userRange == null) {
            userRange = new UserRange();
            userRange.setType(1);
            userRange.setCreateTime(new Date());
            userRange.setValid(true);
            userRange.setOneId(oneId);
            userRange.setTwoId(twoId);
            userRange.setUserId(user.getId());
            userRange.setOneName(oneName);
            userRange.setTwoName(twoName);
            userDao.saveUserRange(userRange);
        } else {
            throw BusinessException.getInstance("不能重复添加相同的");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteRange(ServiceContext serviceContext) {
        String token = serviceContext.getParamsString("token");
        Integer id = serviceContext.getParamsInteger("id");
        userDao.deleteUserRangeById(id);
    }

    public List<Map<String, Object>> getRange(ServiceContext serviceContext) {
        String token = serviceContext.getParamsString("token");
        User user = userDao.findUserByToken(token);
        List<UserRange> userRangeList = userDao.getUserRangeByUserId(user.getId());
        return JsonUtil.objects2List(userRangeList);
    }

    @Transactional(rollbackFor = Exception.class)
    public void verified(ServiceContext serviceContext) {
        String token = serviceContext.getParamsString("token");
        String idCard = serviceContext.getParamsString("idCard");
        Integer userType = serviceContext.getParamsInteger("userType");
        String realName = serviceContext.getParamsString("realName");
        String idCardNegative = serviceContext.getParamsString("idCardNegative");
        String idCardPositive = serviceContext.getParamsString("idCardPositive");
        String certificationImg = serviceContext.getParamsString("certificationImg");
        String agentCompany = serviceContext.getParamsString("agentCompany");
        Integer agentFreeType = serviceContext.getParamsInteger("agentFreeType");
        Integer agentRoleType = serviceContext.getParamsInteger("agentRoleType");
        Integer agentPrice = serviceContext.getParamsInteger("agentPrice");
        User user = userDao.findUserByToken(token);
        if (user.getCertificationStatus() == null || user.getCertificationStatus() != CERTIFICATION_STATUS_3) {
            user.setCertificationType(userType);
            user.setIdCard(idCard);
            user.setRealName(realName);
            user.setIdCardNegative(idCardNegative);
            user.setIdCardPositive(idCardPositive);
            user.setCertificationImg(certificationImg);
            user.setCertificationStatus(CERTIFICATION_STATUS_1);
            //经纪人材料
            user.setAgentFreeType(agentFreeType);
            user.setAgentCompany(agentCompany);
            user.setAgentRoleType(agentRoleType);
            user.setAgentPrice(agentPrice);
            //房东材料
            userDao.saveUser(user);
        }
    }

}
